/**
 * All rights Reserved, Designed By 溪云阁
 * Copyright:    Copyright(C) 2016-2020
 */

package com.module.boots.submit.aspect;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.module.boots.redis.RedisUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 重复提交拦截
 * @author：溪云阁
 * @date：2020年5月24日
 */

@Aspect
@Component
@Slf4j
public class RepeatSubmit {

    @Autowired
    private RedisUtils redisUtils;

    /**
     * 重复提交拦截
     * @author 溪云阁
     * @param pjp
     * @return Object
     */
    @Around(value = "@annotation(com.module.boots.submit.NoRepeatSubmit)")
    public Object arround(ProceedingJoinPoint pjp) {
        Object obj = null;
        try {
            final ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            final String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
            final HttpServletRequest request = attributes.getRequest();
            final HttpServletResponse response = attributes.getResponse();
            final String key = sessionId + "-" + request.getServletPath();
            // 如果缓存中有这个url视为重复提交
            if (redisUtils.get(key) == null) {
                obj = pjp.proceed();
                redisUtils.set(key, 0, 2);
            } else {
                log.error("重复提交");
                response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
                response.setContentType("application/json;charset=UTF-8");
                response.getOutputStream().write(buildFailureMsg("重复提交,请稍后再提交").toString().getBytes("utf-8"));
            }
        }
        catch (final Throwable e) {
            e.printStackTrace();
            log.error("验证重复提交时出现未知异常!");
            return buildFailureMsg("重复提交出现问题");
        }
        return obj;
    }

    /**
     * 自定义错误信息
     * @author 溪云阁
     * @param errMsg
     * @return JSONObject
     */
    private Map<String, Object> buildFailureMsg(String errMsg) {
        final Map<String, Object> json = new ConcurrentHashMap<>();
        json.put("respStatus", "01");
        json.put("respDesc", errMsg);
        json.put("data", null);
        return json;
    }
}
